#include "BtutSunucu.h"

BtutSunucu::BtutSunucu(){
	sunucuBaslat();
	ileticiPtr = NULL;
}

BtutSunucu::~BtutSunucu(){
	sunucuDurdur();
}

void BtutSunucu::sunucuBaslat(){
	// cihazda bluetooth var mi?
	if (sunucu.isValid()) {
		// Bluetooth'u ac:
		sunucu.powerOn();

		// cihaz ismini al:
		sunucuIsmi = sunucu.name();

		// cihazi gorunur yap:
		sunucu.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
			
		servisKur();
      
		rfcommSunucu = new QRfcommServer(this);
		connect(rfcommSunucu, SIGNAL(newConnection()), this, SLOT(istemciBaglandi()));
		rfcommSunucu->listen();
		
	}
	else{
		QMessageBox("Cihazda Bluetooth özelligi yok; yada acilamiyor.");
	}
}

void BtutSunucu::sunucuDurdur(){
	// servisi durdur
	servisBilgisi.unregisterService();

	// soketleri kapat
	qDeleteAll(istemciSoketleri);

	// sunucuyu kapat
	delete rfcommSunucu;
	rfcommSunucu = 0;
}


std::string BtutSunucu::sunucuIsminiVer()
{
	return sunucuIsmi.toStdString();
}

void BtutSunucu::servisKur(	const QString isim = tr("Izci Sunucusu (pilot)"),
							const QString uuid = "e8e10f95-1a70-4b27-9ccf-02010264e9c8",
							const QString aciklama = tr("Android Kablosuz Izci pozisyonlarini gorsellestiren PC sunucu servisi."))
{
	servisBilgisi.setAttribute(	QBluetoothServiceInfo::ServiceName, isim );
	servisBilgisi.setAttribute(	QBluetoothServiceInfo::ServiceDescription, aciklama );
	servisBilgisi.setAttribute(	QBluetoothServiceInfo::ServiceProvider, 
								tr("Munih Yazilim Toplulugu - MUYAT"));
	
	// UUID belirle:
	static const QLatin1String servisUuid(uuid);
	servisBilgisi.setServiceUuid(QBluetoothUuid(servisUuid));
	
	// protokol
	QBluetoothServiceInfo::Sequence protocolDescriptorList;
	QBluetoothServiceInfo::Sequence protocol;
	
	protocol 	<< QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap));
	protocolDescriptorList.append(QVariant::fromValue(protocol));
	
	protocol.clear();
	
	protocol 	<< QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
				<< QVariant::fromValue(quint8(rfcommSunucu->serverPort()));
	protocolDescriptorList.append(QVariant::fromValue(protocol));
	
	servisBilgisi.setAttribute(	QBluetoothServiceInfo::ProtocolDescriptorList,
								protocolDescriptorList);
	
	servisBilgisi.registerService();
}


void BtutSunucu::istemciBaglandi(){
	QBluetoothSocket *soket = rfcommSunucu->nextPendingConnection();
	if (!soket)
	 return;

	connect(soket, SIGNAL(readyRead()), 	this, SLOT(soketiOku()));
	connect(soket, SIGNAL(disconnected()), 	this, SLOT(istemciKoptu()));
	istemciSoketleri.append(soket);

	QString	bildirim;
	bildirim << soket->peerName() << QString(" isimli istemci baglandi."); 
	emit istemciBaglandi(soket->peerName());
	if(ileticiPtr != NULL){
		ileticiPtr->istemciBaglandiIlet(soket->peerName().toStdString());
	}
	else{
		bildirim << QString("Üst uygulamada bir dinleyici henuz abone olmadi."); 
	}
	QMessageBox(bildirim);

}

void BtutSunucu::istemciKoptu(){
	QBluetoothSocket *soket = qobject_cast<QBluetoothSocket *>(sender());
	if (!soket)
		return;

	QString	bildirim;
	bildirim << soket->peerName() << QString(" isimli istemci koptu."); 
	emit istemciKoptu(soket->peerName());
	if(ileticiPtr != NULL){
		ileticiPtr->istemciKoptuIlet(soket->peerName().toStdString());
	}
	else{
		bildirim << QString("Üst uygulamada bir dinleyici henuz abone olmadi."); 
	}
	QMessageBox(bildirim);

	istemciSoketleri.removeOne(soket);
	soket->deleteLater();
}

void BtutSunucu::soketiOku(){
	QBluetoothSocket *soket = qobject_cast<QBluetoothSocket *>(sender());
	if (!soket)
		return;

	while (soket->canReadLine()) {
		QByteArray line = soket->readLine().trimmed();
		emit mesajAlindi( soket->peerName(), QString::fromUtf8(line.constData(), line.length()));
		if(ileticiPtr != NULL){
			ileticiPtr->mesajAlindi( soket->peerName().toStdString(), 
									 QString::fromUtf8(line.constData(), line.length()).toStdString());
		}	
	}
	
	if(ileticiPtr == NULL){
		QMessageBox("Üst uygulamada bir dinleyici henuz abone olmadigi icin veri iletilemiyor.");
	}
}


// tüm soketlere mesaj yollama implementasyonu
void BtutSunucu::mesajYolla(const QString &mesaj){
	QByteArray metin = mesaj.toUtf8() + '\n';

	foreach (QBluetoothSocket *soket, istemciSoketleri)
		soket->write(metin);
}

// tek bir sokete mesaj yollama implementasyonu
void BtutSunucu::mesajYolla(const QString &istemci, const QString &mesaj)
{
	QByteArray metin = mesaj.toUtf8() + '\n';

	foreach (QBluetoothSocket *soket, istemciSoketleri){
		if(soket->peerName() == istemci){
      soket->write(metin);
      }
    }
}

void BtutSunucu::mesajYolla(const std::string &mesaj)
{
	mesajYolla(QString().fromStdString(mesaj));
}

void BtutSunucu::mesajYolla(const std::string &istemci, const std::string &mesaj)
{
	mesajYolla(QString().fromStdString(istemci), QString().fromStdString(mesaj));
}

void BtutSunucu::dinleyiciEkle(const IIletici* IleticiPtr)
{
	ileticiPtr = IleticiPtr;

	QString	bildirim;
	bildirim << QString("Üst uygulamada bir dinleyici abone oldu."); 
	QMessageBox(bildirim);
}


